package com.clj.blesample.notication;

import android.util.Log;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ByteUtil {
    static final String TAG = "ByteUtil";

    /**
     * 把src的数据追加到dest后面
     *
     * @param dest 目标数组
     * @param src  要加入目标的新数组
     * @param pos  新数组的截取的开始
     * @param len  新数组截取的长度
     */
    public static byte[] add(byte[] dest, byte[] src, int pos, int len) {
        dest = Arrays.copyOf(dest, dest.length + len);
        System.arraycopy(src, pos, dest, dest.length - len, len);
        return dest;
    }


    /**
     * 协议封装
     *
     * @param data json参数
     * @param cmd  命令字
     * @return
     */
    public static byte[] sendData(byte[] data, byte[] cmd, byte[] page) {
        byte[] newData = new byte[0];//封装的数据 10
        byte[] byteStart = new byte[]{(byte) 0xF0, (byte) 0xF1};//帧头
        byte[] Version = new byte[]{(byte) 0x09, (byte) 0x00};//协议版本
        if (cmd != null) {
            newData = add(newData, byteStart, 0, byteStart.length);//帧头
            newData = add(newData, Version, 0, Version.length);//协议版本
            newData = add(newData, page, 0, page.length);//序列号
            newData = add(newData, cmd, 0, cmd.length);//命令字
            if (data != null) {
                //有数据体
                newData = add(newData, intToByteBig(data.length), 0, 4);//数据体长度
                newData = add(newData, data, 0, data.length);//数据体
            } else {
                //无数据体
                newData = add(newData, intToByteBig(0), 0, 4);//数据体长度
            }
            //字节累加校验
            byte sum = 0;
            for (int i = 0; i < newData.length; i++) {
                sum += newData[i];
            }
            newData = add(newData, new byte[]{(byte) (sum & 0xff)}, 0, 1);//校验
        }
        return newData;
    }

    /**
     * 新的协议封装-20210623
     * 帧头：1字节，协议版本：1字节，命令字：2字节，key值：2字节，序列号：2字节，数据长度：4字节，数据体：实际，CRC校验：1字节
     *
     * @param data json参数
     * @param cmd  命令字
     * @return
     */
    public static byte[] sendData(byte[] data, byte[] cmd, byte[] key, byte[] index) {
        byte[] newData = new byte[0];//封装的数据 10
        byte[] byteStart = new byte[]{(byte) 0xAB};//帧头
        byte[] Version = new byte[]{(byte) 0x00};//协议版本
        if (cmd != null) {
            newData = add(newData, byteStart, 0, byteStart.length);//帧头
            newData = add(newData, Version, 0, Version.length);//协议版本
            newData = add(newData, cmd, 0, cmd.length);//命令字
            newData = add(newData, key, 0, key.length);//key值
            newData = add(newData, index, 0, index.length);//序列号
            if (data != null) {
                //有数据体
                newData = add(newData, intToByteBig(data.length), 0, 4);//数据体长度
                newData = add(newData, data, 0, data.length);//数据体
            } else {
                //无数据体
                newData = add(newData, intToByteBig(0), 0, 4);//数据体长度
            }
            //字节累加校验
            byte sum = 0;
            for (int i = 0; i < newData.length; i++) {
                sum += newData[i];
                //Log.d("zhanghui","newData[i] = " + newData[i]);
            }
            //Log.d("zhanghui","sum = " + sum);
            newData = add(newData, new byte[]{(byte) (sum & 0xff)}, 0, 1);//校验
        }
        return newData;
    }

    /**
     * 解析数据
     *
     * @param data
     * @return
     */
    public static byte[] getData(byte[] data) {
        byte[] newData = new byte[data.length - 13];
        System.arraycopy(data, 12, newData, 0, data.length - 13);
        return newData;
    }

    /**
     * 校验
     *
     * @param data
     * @return
     */
    public static boolean isSum(byte[] data) {
        byte[] newData = new byte[data.length - 1];
        System.arraycopy(data, 0, newData, 0, data.length - 1);
        Log.d(TAG, "校验数据：" + Arrays.toString(getHexStrings(newData)));
        //字节累加校验
        byte sum = 0;
        for (int i = 0; i < newData.length; i++) {
            sum += newData[i];
        }
        if ((byte) (sum & 0xff) == data[data.length - 1]) {
            return true;
        }
        return false;
    }


    /**
     * 字节数组转HexString
     *
     * @param buff
     * @return
     */
    public static String[] getHexStrings(byte[] buff) {
        List<String> templist = new ArrayList<>();
        for (int i = 0; i < buff.length; i++) {
            String hex = Integer.toHexString(buff[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            hex = "0x" + hex;
            templist.add(hex);
        }
        return templist.toArray(new String[0]);
    }

    /**
     * 转换成大端模式-高字节在前(java为高字节在前,内存数组第0位表示最前)
     */
    public static byte[] intToByte4B(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n >> 24 & 0xff); //数据组起始位,存放内存起始位, 即:高字节在前
        b[1] = (byte) (n >> 16 & 0xff); //高字节在前是与java存放内存一样的, 与书写顺序一样
        b[2] = (byte) (n >> 8 & 0xff);
        b[3] = (byte) (n & 0xff);
        return b;
    }

    /**
     * 将int转为高字节在前，低字节在后的byte数组（大端）
     *
     * @param n int
     * @return byte[]
     */
    public static byte[] intToByteBig(int n) {
        byte[] b = new byte[4];
        b[3] = (byte) (n & 0xff);
        b[2] = (byte) (n >> 8 & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[0] = (byte) (n >> 24 & 0xff);
        return b;
    }

    /**
     * 将short转为高字节在前，低字节在后的byte数组（大端）
     *
     * @param n short
     * @return byte[]
     */
    public static byte[] shortToByteBig(short n) {
        byte[] b = new byte[2];
        b[1] = (byte) (n & 0xff);
        b[0] = (byte) (n >> 8 & 0xff);
        return b;
    }

    /**
     * 按照李满需求格式话应用包名，然后才可以在手表通知中显示
     *
     * @param pkg
     * @return
     */
    public static String convertPakageName(String pkg) {
        //短信
        if (pkg.equals("com.android.mms.service") //vivo手机包名-----最新短信
                || pkg.equals("com.android.mms"))//所有品牌手机系统包名
        {
            pkg = "com.mms";
        } else if (pkg.equals("com.android.phone")//电话
                || pkg.equals("com.android.incallui") //所有品牌手机系统包名
                || pkg.equals("com.android.contacts")//华为所有手机包名---未接来电通知
                || pkg.equals("com.android.server.telecom")//红米K30 5G---未接来电通知
        ) {
            pkg = "com.dialer";
        }
        return pkg;
    }
}
